001 /**
002 * Copyright 2003-2004 The Apache Software Foundation
003 * Copyright 2005 Stephen McConnell
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package net.dpml.cli.builder;
018
019 import java.util.HashSet;
020 import java.util.Iterator;
021 import java.util.Set;
022
023 import net.dpml.cli.Argument;
024 import net.dpml.cli.Option;
025 import net.dpml.cli.validation.ClassValidator;
026 import net.dpml.cli.validation.DateValidator;
027 import net.dpml.cli.validation.FileValidator;
028 import net.dpml.cli.validation.NumberValidator;
029 import net.dpml.cli.validation.URLValidator;
030 import net.dpml.cli.validation.Validator;
031
032 /**
033 * Builds Options using a String pattern
034 *
035 * @author <a href="http://www.dpml.net">Digital Product Meta Library</a>
036 * @version 1.0.0
037 */
038 public class PatternBuilder
039 {
040 private final GroupBuilder m_gbuilder;
041 private final DefaultOptionBuilder m_obuilder;
042 private final ArgumentBuilder m_abuilder;
043 private final Set m_options = new HashSet();
044
045 /**
046 * Creates a new PatternBuilder
047 */
048 public PatternBuilder()
049 {
050 this(
051 new GroupBuilder(),
052 new DefaultOptionBuilder(),
053 new ArgumentBuilder() );
054 }
055
056 /**
057 * Creates a new PatternBuilder
058 * @param gbuilder the GroupBuilder to use
059 * @param obuilder the DefaultOptionBuilder to use
060 * @param abuilder the ArgumentBuilder to use
061 */
062 public PatternBuilder(
063 final GroupBuilder gbuilder,
064 final DefaultOptionBuilder obuilder,
065 final ArgumentBuilder abuilder )
066 {
067 m_gbuilder = gbuilder;
068 m_obuilder = obuilder;
069 m_abuilder = abuilder;
070 }
071
072 /**
073 * Creates a new Option instance.
074 * @return a new Option instance
075 */
076 public Option create()
077 {
078 final Option option;
079 if( m_options.size() == 1 )
080 {
081 option = (Option) m_options.iterator().next();
082 }
083 else
084 {
085 m_gbuilder.reset();
086 for( final Iterator i = m_options.iterator(); i.hasNext();)
087 {
088 m_gbuilder.withOption( (Option) i.next() );
089 }
090 option = m_gbuilder.create();
091 }
092 reset();
093 return option;
094 }
095
096 /**
097 * Resets this builder
098 * @return the builder
099 */
100 public PatternBuilder reset()
101 {
102 m_options.clear();
103 return this;
104 }
105
106 private void createOption( final char type, final boolean required, final char opt )
107 {
108 final Argument argument;
109 if( type != ' ' )
110 {
111 m_abuilder.reset();
112 m_abuilder.withValidator( validator( type ) );
113 if( required )
114 {
115 m_abuilder.withMinimum( 1 );
116 }
117 if( type != '*' )
118 {
119 m_abuilder.withMaximum( 1 );
120 }
121 argument = m_abuilder.create();
122 }
123 else
124 {
125 argument = null;
126 }
127
128 m_obuilder.reset();
129 m_obuilder.withArgument( argument );
130 m_obuilder.withShortName( String.valueOf( opt ) );
131 m_obuilder.withRequired( required );
132 m_options.add( m_obuilder.create() );
133 }
134
135 /**
136 * Builds an Option using a pattern string.
137 * @param pattern the pattern to build from
138 */
139 public void withPattern( final String pattern )
140 {
141 int sz = pattern.length();
142 char opt = ' ';
143 char ch = ' ';
144 char type = ' ';
145 boolean required = false;
146
147 for( int i=0; i < sz; i++ )
148 {
149 ch = pattern.charAt( i );
150 switch( ch )
151 {
152 case '!' :
153 required = true;
154 break;
155 case '@' :
156 case ':' :
157 case '%' :
158 case '+' :
159 case '#' :
160 case '<' :
161 case '>' :
162 case '*' :
163 case '/' :
164 type = ch;
165 break;
166 default :
167 if( opt != ' ' )
168 {
169 createOption( type, required, opt );
170 required = false;
171 type = ' ';
172 }
173 opt = ch;
174 }
175 }
176 if( opt != ' ' )
177 {
178 createOption( type, required, opt );
179 }
180 }
181
182 private static Validator validator( final char c )
183 {
184 switch( c )
185 {
186 case '@' :
187 final ClassValidator classv = new ClassValidator();
188 classv.setInstance( true );
189 return classv;
190 case '+' :
191 final ClassValidator instancev = new ClassValidator();
192 return instancev;
193 //case ':':// no validator needed for a string
194 case '%' :
195 return NumberValidator.getNumberInstance();
196 case '#' :
197 return DateValidator.getDateInstance();
198 case '<' :
199 final FileValidator existingv = new FileValidator();
200 existingv.setExisting( true );
201 existingv.setFile( true );
202 return existingv;
203 case '>' :
204 case '*' :
205 return new FileValidator();
206 case '/' :
207 return new URLValidator();
208 default :
209 return null;
210 }
211 }
212 }